package gui.frame;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;

import metaballs.MetaBallTexture;
import metaballs.MetaballSystem;

import util.BasicGraphicsJogl;
import util.Vec2F;
import util.texture.StockTextureFactory;
import util.texture.textureGenerators.InverseRSquaredTextureGenerator;
import util.texture.textureGenerators.BaseFloatTextureDataGenerator;

import com.sun.opengl.util.Animator;
import com.sun.opengl.util.FPSAnimator;
import com.sun.opengl.util.texture.Texture;

public class GuiGLFrame extends Frame implements GLEventListener, WindowListener
{
	private Animator animator;
	private Vec2F dims;
	private int programHandle;
	private int textGenTexture;
	private int frame = 0;
	private MetaBallTexture metaballTexture;
	private MetaballSystem ms;
	private long lastFrameStart;
	private boolean firstFrame = true;
	Texture faceTexture = null;
    private BasicGraphicsJogl basicGraphicsJogl;
	//	private GuiRootComponent guiRootComponent;
	public GuiGLFrame(String caption,int width,int height) 
	{
		super(caption);
        GLCanvas canvas = new GLCanvas();

        canvas.addGLEventListener(this);
        add(canvas);
        setSize(width, height);
        
        animator = new FPSAnimator(canvas, 60);
        animator.start();
        addWindowListener(this);
        setVisible(true);
        dims = new Vec2F(width,height);		
	} 
	
	@Override
	public void display(GLAutoDrawable drawable) 
	{
		GL gl = basicGraphicsJogl.getGL();

		float timeElapsed;
		if(firstFrame)
		{
			timeElapsed = 0.0f;
			firstFrame = false;
			lastFrameStart = System.nanoTime();
		}
		else
		{
			timeElapsed = (System.nanoTime() - lastFrameStart) / 1000000000.0f;
			lastFrameStart = System.nanoTime();
		}
		ms.update(timeElapsed);
		
		gl.glClear(GL.GL_COLOR_BUFFER_BIT);// | GL.GL_DEPTH_BUFFER_BIT);
		gl.glLoadIdentity();
		gl.glEnable(GL.GL_TEXTURE_2D);
		
		ms.render(new Vec2F(350,350));
//		basicGraphics.drawCenteredImage(faceTexture, new Vec2F(300f,300f + frame/10.0f));
		frame++;
//		renderMetaballsToTexture();
//		basicGraphics.setShaderProgram(programHandle);
		
//		basicGraphics.drawCenteredImage(illegalTexture, new Vec2F(128,80));
//		basicGraphics.drawCenteredImage(metaballTexture, new Vec2F(128,128));
//		frame++;
	}
	

	public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) 
	{

	}

	public void init(GLAutoDrawable drawable) 
	{
        final GL gl = drawable.getGL();
        gl.glShadeModel(GL.GL_SMOOTH);
        gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        gl.setSwapInterval(1);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);// | GL.GL_DEPTH_BUFFER_BIT);
        gl.glEnable(GL.GL_TEXTURE_2D);
        gl.glEnable (GL.GL_BLEND); 
        gl.glBlendFunc (GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
	    
	    basicGraphicsJogl = new BasicGraphicsJogl(drawable.getContext());
        
		try
		{
			faceTexture = StockTextureFactory.createImageTexture("/resources/facesmall.png");
		} 
		catch (IOException e)
		{
			assert false: "Cannot load texture";
		}
		
		BaseFloatTextureDataGenerator t = new InverseRSquaredTextureGenerator(0.01f,0.06f);
        metaballTexture = new MetaBallTexture(new Dimension(128,128),t);
		ms = new MetaballSystem(300, 
								10000,
								metaballTexture,
								faceTexture,
								new Dimension(512,512));
		

	}

	public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) 
	{
		final GL gl = drawable.getGL();
		final GLU glu = new GLU();
		
		gl.setSwapInterval(1);

		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL.GL_PROJECTION);
		gl.glLoadIdentity();
		glu.gluOrtho2D(0, width, height, 0);
		gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glLoadIdentity();
		gl.glClear(GL.GL_COLOR_BUFFER_BIT);// | GL.GL_DEPTH_BUFFER_BIT);
	}
	
	
	@Override
	public void windowActivated(WindowEvent e)
	{
		// TODO Auto-generated method stub
		
	}
	@Override
	public void windowClosed(WindowEvent e)
	{
	}
	@Override
	public void windowClosing(WindowEvent e)
	{
        animator.stop();
        System.exit(0);
	}
	@Override
	public void windowDeactivated(WindowEvent e)
	{
		// TODO Auto-generated method stub
		
	}
	@Override
	public void windowDeiconified(WindowEvent e)
	{
		// TODO Auto-generated method stub
		
	}
	@Override
	public void windowIconified(WindowEvent e)
	{
		// TODO Auto-generated method stub
		
	}
	@Override
	public void windowOpened(WindowEvent e)
	{
		// TODO Auto-generated method stub
		
	}
	public Vec2F getDims()
	{
		return dims;
	}
	public void setDims(Vec2F dims)
	{
		this.dims = dims;
	}
	private static final long serialVersionUID = -7446145777169932476L;
}
